#ifndef __HW_PTZ_SERVICE_H__
#define __HW_PTZ_SERVICE_H__

#include "utils_misc.h"
#include "sdc.h"
#include "sdc_def_ext.h"
#include "hw_app_log.h"

#define sdc_extend_head_length(extend_head) (((extend_head)->length + 7) & ~7)

namespace gc {

class PtzService : public Singleton<PtzService> {
public:
    int GetPresetInfos(std::vector<sdc_preset_info>* preset_infos)
    {
        int nret, i;
        char buf[1024] = { 0 };
        struct sdc_preset_info *info;
        sdc_common_head_s *head = (sdc_common_head_s *)buf;
        /** query all channels' info */
        head->version = SDC_VERSION;          // 0x5331
        head->url = PTZ_URL_PRESET_POSITION;  // 0x00
        head->method = SDC_METHOD_GET;        // 0x02
        head->head_length = sizeof(*head);

        nret = write(fd_ptz, head, head->head_length + head->content_length);
        if (nret < 0) {
            fprintf(stdout, "write fail GetPresetInfos,response:%d,url:%d,code:%d,method:%d\n", head->response,
                    head->url, head->code, head->method);
            return errno;
        }
        nret = read(fd_ptz, buf, sizeof(buf));
        if (nret < 0 || head->code != SDC_CODE_200) {
            fprintf(stdout, "read fail response:%d,url:%d,code:%d, method:%d\n", head->response, head->url, head->code,
                    head->method);
            return errno;
        }

        for (i = 0, info = (struct sdc_preset_info *)&buf[head->head_length]; i < head->content_length / sizeof(*info); ++i, ++info) {
            LOG_INFO("ID %d \n", info->preset_id);
            LOG_INFO("Hl %lf \n", info->preset_attr.preset_position.h_location);
            LOG_INFO("Vl %lf \n", info->preset_attr.preset_position.v_location);
            LOG_INFO("fp %lld \n", info->preset_attr.preset_position.focus_pos);
            LOG_INFO("zp %lld \n", info->preset_attr.preset_position.zoom_pos);
            preset_infos->push_back(*info);
        }
        return HW_OK;
    }

    int GetCurrentLocation(sdc_preset_pos &preset_pos, int *moving)
    {
        int nret, i;
        char buf[1024] = { 0 };
        sdc_common_head_s *head = (sdc_common_head_s *)buf;
        sdc_extend_head_s content_head = {
            SDC_HEAD_PTZ_CONTENT_TYPE, sizeof(content_head),
            CONTENT_TYPE_PRESET_POS
        };
        head->version = SDC_VERSION;    // 0x5331
        head->url = PTZ_URL_LOCATION;   // 0x01
        head->method = SDC_METHOD_GET;  // 0x02
        head->head_length = sizeof(*head);

        nret = write(fd_ptz, head, head->head_length + head->content_length);
        if (nret < 0) {
            LOG_ERROR("write fail GetCurrentLocation response:%d, url:%d, code:%d, method:%d\n", head->response, head->url, head->code, head->method);
            return errno;
        }
        nret = read(fd_ptz, buf, sizeof(buf));
        if (nret < 0 || head->code != SDC_CODE_200) {
            LOG_ERROR("read fail GetCurrentLocation response:%d, url:%d, code:%d, method:%d\n", head->response, head->url, head->code, head->method);
            return errno;
        }
        content_head = *(sdc_extend_head_s*) &buf[sizeof(*head)];
        preset_pos = *(struct sdc_preset_pos *)&buf[head->head_length];
        LOG_DEBUG("reserve %d \n", content_head.reserve);  // 扩展头Reserve字段的取值为0代表摄像机处于静止状态，1代表运动中状态
        *moving = content_head.reserve;
        LOG_DEBUG("Hl %lf \n", preset_pos.h_location);
        LOG_DEBUG("Vl %lf \n", preset_pos.v_location);
        LOG_DEBUG("fp %lld \n", preset_pos.focus_pos);
        LOG_DEBUG("zp %lld \n", preset_pos.zoom_pos);

        return HW_OK;
    }
};

}  // namespace gc

#endif /* __HW_PTZ_SERVICE_H__ */